package com.lelouch.bestpractice.mongorepository.shiro.config;

import com.lelouch.bestpractice.mongorepository.shiro.credential.CredentialsMatcher;
import com.lelouch.bestpractice.mongorepository.shiro.realm.LoginRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Shiro的配置类
 *
 * @author lcy
 * @create 2018-09-17 10:46
 */
@Configuration
public class ShiroConfiguration {
    @Bean
    public ModularRealmAuthenticator authenticator(){
        ModularRealmAuthenticator modularRealmAuthenticator=new ModularRealmAuthenticator();
        modularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return modularRealmAuthenticator;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
        defaultWebSecurityManager.setAuthenticator(authenticator());
        defaultWebSecurityManager.setRealm(loginRealm());
        return defaultWebSecurityManager;
    }

    @Bean
    public LoginRealm loginRealm(){
        LoginRealm loginRealm = new LoginRealm();
        //CredentialsMatcher credentialsMatcher = new CredentialsMatcher();
        //HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        //hashedCredentialsMatcher.setHashIterations(1024);
        //loginRealm.setCredentialsMatcher(credentialsMatcher);

        return loginRealm;
    }

    //@Bean
    //public SecondRealm secondRealm(){
    //    SecondRealm secondRealm = new SecondRealm();
    //    return secondRealm;
    //}

    @Bean
    public ShiroFilterFactoryBean shiroFilter(){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        //如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/shiro/loginindex");
        shiroFilterFactoryBean.setSuccessUrl("/shiro/list");
        //shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized.jsp");


        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        //配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/shiro/loginindex", "anon");
        filterChainDefinitionMap.put("/shiro/logout", "logout");
        filterChainDefinitionMap.put("/login.jsp", "anon");
        filterChainDefinitionMap.put("/shiro/login", "anon");
        filterChainDefinitionMap.put("/user.jsp", "roles[user]");
        filterChainDefinitionMap.put("/admin.jsp", "roles[admin]");
        filterChainDefinitionMap.put("/**", "anon");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }


    //// 会话管理器，设定会话超时及保存
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        //Collection<SessionListener> listeners = new ArrayList<SessionListener>();
        //listeners.add(new ShiroSessionListener());
        //sessionManager.setSessionListeners(listeners);
        sessionManager.setGlobalSessionTimeout(1800000); //全局会话超时时间（单位毫秒），默认30分钟
        // sessionManager.setSessionDAO(sessionDAO());
        sessionManager.setDeleteInvalidSessions(true);
        sessionManager.setSessionValidationSchedulerEnabled(true);
        //定时清理失效会话, 清理用户直接关闭浏览器造成的孤立会话
        sessionManager.setSessionValidationInterval(1800000);
//      sessionManager.setSessionValidationScheduler(executorServiceSessionValidationScheduler());
        sessionManager.setSessionIdCookieEnabled(true);
        // sessionManager.setSessionIdCookie(rememberMeCookie());
        return sessionManager;
    }

}
